﻿using System;

namespace GenericKnowledge
{
    class Program
    {
        static void Main(string[] args)
        {
            //Console.WriteLine("Hello World!");

            //TestCovariance();

            //TestInterfaceCovariance();
            ////测试协变
            //TestContravariance();

            Console.WriteLine("========================01测试泛型基础========================");
            _01StatckT<int> intStack = new _01StatckT<int>();
            intStack.Push(1);
            intStack.Push(2);
            intStack.Push(3);
            var cloneStatlc = intStack.Clone();
            cloneStatlc.Push(1);
            cloneStatlc.Push(2);
            cloneStatlc.Push(4);
            Console.WriteLine(intStack.Pop());
            Console.WriteLine(cloneStatlc.Pop());

            Console.WriteLine("==========================02测试泛型方法=====================");
            _02GenericMethod _02GenericMethod = new _02GenericMethod();
            int x = 100; int y = 200;
            _02GenericMethod.Swap(ref x, ref y);
            Console.WriteLine($"交换完成之后的值是 x{x},y{y}");
            string value1 = "Hello";
            string value2 = "world";
            _02GenericMethod.Swap(ref value1, ref value2);
            Console.WriteLine($"字符串交换完成后之后的数据是 value1{value1},value2{value2}");


            Console.WriteLine("==========================03测试自引用泛型=====================");
            _03ShelfReferenceGeneric _03ShelfReferenceGeneric = new _03ShelfReferenceGeneric();
            _03ShelfReferenceGeneric.Colcor = "123";
            _03ShelfReferenceGeneric.Name = "123";

            _03ShelfReferenceGeneric _03ShelfReferenceGeneric2 = new _03ShelfReferenceGeneric();
            _03ShelfReferenceGeneric2.Colcor = "123";
            _03ShelfReferenceGeneric2.Name = "1236";
            var result = _03ShelfReferenceGeneric.Equals(_03ShelfReferenceGeneric2);
            Console.WriteLine(result);

            Console.WriteLine("=============================04测试协变==========================");
            TestInterfaceCovariance();
        }

        static void TestCovariance()
        {
            //StatckT<Animal> animals = new StatckT<Animal>();
            //StatckT<Cat> cats = new StatckT<Cat>();

            //StatckT<Animal> animals2 = cats;

            Animal animal = new Animal();
            animal.Name = "Animal";
            Wash<Animal>(animal);

            Dog dog = new Dog();
            dog.Name = "dog";
            Wash(dog);

        }

        static void Wash<T>(T t) where T : Animal
        {
            string whoWash = t.Wash();
            Console.WriteLine(whoWash);
        }


        static void TestInterfaceCovariance()
        {
            Dog dog = new Dog();
            dog.Name = "Dog";
            _01StatckT<Dog> dogs = new _01StatckT<Dog>();
            dogs.Push(dog);

            IPopable<Animal> animals = dogs;
            Animal animal = animals.Pop();
           Console.WriteLine(animal.Name);

        }
        //逆变测试
        static void TestContravariance()
        {

            IPushable<Animal> pushableAnimals = new _01StatckT<Animal>();
            IPushable<Dog> pushableDogs = pushableAnimals;
            pushableDogs.Push(new Dog() { Name = "Dog" });




        }
    }



}
